;------------------------------------------------------------------------------
;
; Copyright (c) 2005 - 2007, Intel Corporation                                                         
; All rights reserved. This program and the accompanying materials                          
; are licensed and made available under the terms and conditions of the BSD License         
; which accompanies this distribution.  The full text of the license may be found at        
; http://opensource.org/licenses/bsd-license.php                                            
;                                                                                           
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
; 
; Module Name:
;   ProcessorAsms.Asm
;
; Abstract:
;   This is separated from processor.c to allow this functions to be built with /O1
;
;
;------------------------------------------------------------------------------

text  SEGMENT


;
; Routine Description:
;   This allows the caller to switch the stack and goes to the new entry point
;
; Arguments:
;   EntryPoint      - Pointer to the location to enter // rcx
;   Parameter       - Parameter to pass in             // rdx
;   NewStack        - New Location of the stack        // r8
;   NewBsp          - New BSP                          // r9 - not used
;
; Returns:
;   Nothing. Goes to the Entry Point passing in the new parameters
;
SwitchStacks  PROC  PUBLIC

    ; Adjust stack for
    ;   1) leave 4 registers space
    ;   2) let it 16 bytes aligned after call
    sub   r8, 20h
    and   r8w, 0fff0h    ; do not assume 16 bytes aligned

    mov   rsp,  r8       ; rsp = NewStack
    mov   r10,  rcx      ; save EntryPoint
    mov   rcx,  rdx      ; Arg1 = Parameter
    call  r10            ; r10 = copy of EntryPoint
 ;
 ; no ret as we have a new stack and we jumped to the new location
 ;     
    ret
  
SwitchStacks    ENDP


EFI_SUCCESS                     equ     0
EFI_WARN_RETURN_FROM_LONG_JUMP  equ     5

;
; Generated by h2inc run manually
;
_EFI_JUMP_BUFFER                STRUCT 2t
_rbx            QWORD           ?
_rsp            QWORD           ?
_rbp            QWORD           ?
_rdi            QWORD           ?
_rsi            QWORD           ?
_r10            QWORD           ?
_r11            QWORD           ?
_r12            QWORD           ?
_r13            QWORD           ?
_r14            QWORD           ?
_r15            QWORD           ?
_rip            QWORD           ?
_EFI_JUMP_BUFFER                ENDS

EFI_JUMP_BUFFER         TYPEDEF         _EFI_JUMP_BUFFER


;
;Routine Description:
;
;  This routine implements the x64 variant of the SetJump call.  Its
;  responsibility is to store system state information for a possible
;  subsequent LongJump.
;
;Arguments:
;
;  Pointer to CPU context save buffer.
;
;Returns:
;
;  EFI_SUCCESS
;
; EFI_STATUS
; EFIAPI
; TransferControlLongJump (
;   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,
;   IN EFI_JUMP_BUFFER                    *Jump
;   );
;
; rcx - *This
; rdx - JumpBuffer
;
PUBLIC  TransferControlSetJump
TransferControlSetJump  PROC  
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rbx, rbx
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rsp, rsp
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rbp, rbp
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rdi, rdi
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rsi, rsi
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r10, r10
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r11, r11
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r12, r12
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r13, r13
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r14, r14
  mov   (EFI_JUMP_BUFFER PTR [rdx])._r15, r15
  mov   rax, QWORD PTR [rsp+0]
  mov   (EFI_JUMP_BUFFER PTR [rdx])._rip, rax
  mov   rax, EFI_SUCCESS  
  ret
  
TransferControlSetJump      ENDP

;
; EFI_STATUS
; EFIAPI
; TransferControlLongJump (
;   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,  // rcx
;   IN EFI_JUMP_BUFFER                    *Jump   // rdx
;   );
;
;
PUBLIC  TransferControlLongJump
TransferControlLongJump  PROC  
  ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
  mov   rax, EFI_WARN_RETURN_FROM_LONG_JUMP          
  mov   rbx, (EFI_JUMP_BUFFER PTR [rdx])._rbx
  mov   rsp, (EFI_JUMP_BUFFER PTR [rdx])._rsp
  mov   rbp, (EFI_JUMP_BUFFER PTR [rdx])._rbp
  mov   rdi, (EFI_JUMP_BUFFER PTR [rdx])._rdi
  mov   rsi, (EFI_JUMP_BUFFER PTR [rdx])._rsi
  mov   r10, (EFI_JUMP_BUFFER PTR [rdx])._r10
  mov   r11, (EFI_JUMP_BUFFER PTR [rdx])._r11
  mov   r12, (EFI_JUMP_BUFFER PTR [rdx])._r12
  mov   r13, (EFI_JUMP_BUFFER PTR [rdx])._r13
  mov   r14, (EFI_JUMP_BUFFER PTR [rdx])._r14
  mov   r15, (EFI_JUMP_BUFFER PTR [rdx])._r15
  add   rsp, 8                                       ;pop the eip
  jmp   QWORD PTR (EFI_JUMP_BUFFER PTR [rdx])._rip
  ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
  mov   rax, EFI_WARN_RETURN_FROM_LONG_JUMP
  ret
TransferControlLongJump  ENDP

text  ENDS
END
